<template>
  <template v-if="loading">
    <div class="loading">
      <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px" height="30px" viewBox="0 0 24 30" xml:space="preserve">
        <rect x="0" y="10" width="4" height="10" opacity="0.2">
          <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0s" dur="0.6s" repeatCount="indefinite" />
          <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0s" dur="0.6s" repeatCount="indefinite" />
          <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0s" dur="0.6s" repeatCount="indefinite" />
        </rect>
        <rect x="8" y="10" width="4" height="10" opacity="0.2">
          <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0.15s" dur="0.6s" repeatCount="indefinite" />
          <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0.15s" dur="0.6s" repeatCount="indefinite" />
          <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0.15s" dur="0.6s" repeatCount="indefinite" />
        </rect>
        <rect x="16" y="10" width="4" height="10" opacity="0.2">
          <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0.3s" dur="0.6s" repeatCount="indefinite" />
          <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0.3s" dur="0.6s" repeatCount="indefinite" />
          <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0.3s" dur="0.6s" repeatCount="indefinite" />
        </rect>
      </svg>
    </div>
  </template>

  <template v-else-if="isError">
    <div class="error">
      <svg t="1658374799278" class="icon" viewBox="0 0 1277 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2638" width="200" height="200">
        <path d="M626.837443 683.02998c-20.587783 2.058778-39.116788 11.928804-52.135533 27.914612a76.598664 76.598664 0 0 0-17.196854 56.555851l2.664301 25.371416 2.482645-2.543197c10.959967 27.672403 37.905742 46.988587 68.545207 46.988587 3.69369 0 7.387381-0.181657 10.77831-0.484418a77.446396 77.446396 0 0 0 69.392939-84.470463 78.051919 78.051919 0 0 0-84.531015-69.332388z" p-id="2639"></path>
        <path d="M1244.168175 926.268583L682.061144 44.384838a57.888002 57.888002 0 0 0-57.706345-23.91816 57.706345 57.706345 0 0 0-37.421324 24.281474L24.826444 926.147478a50.379516 50.379516 0 0 0-8.053456 28.035716c2.058778 28.338478 25.25031 49.652889 53.286027 49.652889l2.36154-0.060552 1123.669091-0.060553a53.528236 53.528236 0 0 0 55.950328-49.592336l0.060552-3.027615a48.260186 48.260186 0 0 0-7.932351-24.826444z m-172.574065-39.722311H197.218852l437.248181-685.63373 437.127077 685.63373z" p-id="2640"></path>
        <path d="M601.466028 372.033351a22.888771 22.888771 0 0 0-22.525457 21.919934l0.060553 226.162852c0.726628 11.807699 10.717758 21.193306 22.464904 21.193307h0.666075l64.124889-0.121105h0.968837a22.767666 22.767666 0 0 0 22.525457-21.919934V393.347762a23.009875 23.009875 0 0 0-22.949323-21.314411H601.466028z" p-id="2641"></path>
      </svg>
      <span>出错了</span>
    </div>
  </template>

  <template v-else-if="finished">
    <div class="finished">
      <div class="page-endpic anim" aria-hidden="true">
        <div class="page-endpic-paper">
          <span class="page-endpic-paper-line l1"></span>
          <span class="page-endpic-paper-line l2"></span>
          <span class="page-endpic-paper-line l3"></span>
          <span class="page-endpic-paper-line l4"></span>
          <span class="page-endpic-paper-line l5"></span>
          <span class="page-endpic-angle-shadow"></span>
        </div>
        <div class="page-endpic-icon page-endpic-icon_finish">
          <svg viewBox="-1 -1 72 72" id="icon-success" fill-rule="evenodd" width="100%" height="100%">
            <path class="page-endpic-icon-circle" d="M35,0c19.33,0,35,15.67,35,35S54.33,70,35,70c-6.495,0-12.578-1.77-17.791-4.853c-2.477-1.465-14.098,1.741-14.098,1.741S6.856,55.979,5.43,53.733C1.991,48.316,0,41.891,0,35C0,15.67,15.67,0,35,0z"></path>
            <path class="page-endpic-icon-check" d="M27.515,44.729l21.214-21.214l4.242,4.243L31.757,48.971L27.515,44.729z"></path>
            <path class="page-endpic-icon-check" d="M19.029,36.242L23.272,32L36,44.729l-4.243,4.242L19.029,36.242z"></path>
          </svg>
        </div>
      </div>
      <p>感谢你的填写，问卷已成功提交！</p>
    </div>
  </template>

  <template v-else>
    <h1 class="title">{{ title }}</h1>
    <p class="info">{{ info }}</p>

    <QuestionList :questions="questions" :collect-template="collectTemplate" @fill="fillQuestions"></QuestionList>

    <div class="submit">
      <span class="loading" v-if="submitting">
        <span>正在提交</span>
        <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px" height="30px" viewBox="0 0 24 30" style="enable-background: new 0 0 50 50" xml:space="preserve">
          <rect x="0" y="10" width="4" height="10" fill="#333" opacity="0.2">
            <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0s" dur="0.6s" repeatCount="indefinite" />
            <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0s" dur="0.6s" repeatCount="indefinite" />
            <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0s" dur="0.6s" repeatCount="indefinite" />
          </rect>
          <rect x="8" y="10" width="4" height="10" fill="#333" opacity="0.2">
            <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0.15s" dur="0.6s" repeatCount="indefinite" />
            <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0.15s" dur="0.6s" repeatCount="indefinite" />
            <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0.15s" dur="0.6s" repeatCount="indefinite" />
          </rect>
          <rect x="16" y="10" width="4" height="10" fill="#333" opacity="0.2">
            <animate attributeName="opacity" attributeType="XML" values="0.2; 1; .2" begin="0.3s" dur="0.6s" repeatCount="indefinite" />
            <animate attributeName="height" attributeType="XML" values="10; 20; 10" begin="0.3s" dur="0.6s" repeatCount="indefinite" />
            <animate attributeName="y" attributeType="XML" values="10; 5; 10" begin="0.3s" dur="0.6s" repeatCount="indefinite" />
          </rect>
        </svg>
      </span>
      <button @click="submit">提交</button>
    </div>
  </template>
</template>

<script>
import getSurvey from '@/request/getSurvey'
import postAnswer from '@/request/postAnswer'
import QuestionList from '../components/QuestionList.vue'
import { isNotNil } from '@/utils/utils'

export default {
  components: { QuestionList },
  data() {
    return {
      title: '',
      info: '',
      questions: [],
      collectTemplate: [],

      loading: true,
      isError: false,
      finished: false,
      submitting: false,
    }
  },
  methods: {
    // 提示用户填写必填题目
    noticeFill(questionId) {
      const questions = JSON.parse(JSON.stringify(this.questions))
      questions.some(q => {
        if (q.id === questionId) {
          this.$msg(`第 ${q.seq} 题未完成`, 'error')
          return true
        }
      })
    },

    // 初始化问卷题目
    async initSurvey() {
      try {
        const { drawTemplate, collectTemplate } = await getSurvey()
        this.title = drawTemplate.title
        this.info = drawTemplate.info
        this.questions = drawTemplate.questions
        this.collectTemplate = collectTemplate
        // this.loadCache()
      } catch (error) {
        // NOTE: 此处的捕获错误, 仅针对 await getSurvey(), 故直接输出 error
        this.$msg(error, 'error')
        this.isError = true
      }
      this.loading = false
    },

    fillQuestions(collectTemplate) {
      this.collectTemplate = collectTemplate
      // window.localStorage.setItem('answer', JSON.stringify(collectTemplate))
    },

    // 确保必填的都填写了, 返回 true 代表 校验通过
    check() {
      const collectData = JSON.parse(JSON.stringify(this.collectTemplate))

      return collectData.every(collect => {
        if (!collect.required) return true

        // NOTE: 因为收集的答案中, text、options、group 的存在是互斥的, 所以才可采用这种判断方式
        if (isNotNil(collect.text) || isNotNil(collect.options) || isNotNil(collect.groups)) {
          return true
        }

        this.noticeFill(collect.id)
        return false
      })
    },

    // 点击提交
    async submit() {
      if (!this.check()) {
        return
      }
      this.submitting = true
      try {
        // NOTE: 此 Proxy 对象在 postAnswer 中进行处理
        await postAnswer(this.collectTemplate)
        this.$msg('提交成功', 'success')
        this.finished = true
        window.localStorage.setItem('answer', '')
      } catch (error) {
        // NOTE: 此处的捕获错误, 仅针对 await postAnswer(), 故直接输出 error
        this.$msg(error, 'error')
      }
      this.submitting = false
    },
  },
  mounted() {
    this.initSurvey()
  },
}
</script>

<style lang="scss">
.loading {
  width: 100%;
  overflow: hidden;
  height: 100px;
  display: grid;
  place-content: center;
  transform: scale(3);
  svg {
    fill: #1f6ce5;
  }
}
.error {
  height: 200px;
  display: grid;
  place-content: center;
  text-align: center;
  font-size: 30px;
  animation: slide-in-bck-center 0.4s 0.1s linear both;

  @keyframes slide-in-bck-center {
    0% {
      opacity: 0;
      transform: scale(0.3, 0.5) translate(-3px, 23px);
    }

    30% {
      opacity: 1;
      transform: scale(1.15, 1.13) translate(1px, 0px);
    }

    60% {
      opacity: 1;
      transform: scale(0.96, 0.98) translate(0px, 0px);
    }

    80% {
      opacity: 1;
      transform: scale(1.12, 1.11) translate(0px, 0px);
    }

    100% {
      opacity: 1;
      transform: scale(1, 1) translate(0px, 0px);
    }
  }
  svg {
    fill: #f00;
  }
}
.finished {
  display: grid;
  place-content: center;
  text-align: center;
  font-size: 20px;
  .page-endpic {
    position: relative;
    width: 106px;
    height: 128px;
    margin: 0 auto;
    .page-endpic-paper {
      position: relative;
      width: 106px;
      height: 128px;
      border-radius: 5px;
      background: linear-gradient(to bottom, #ebebeb 0%, #d9d9d9 100%);

      &::before {
        content: '';
        position: absolute;
        right: 0;
        top: 0;
        width: 0;
        height: 0;
        border-top: 14px solid #f1f1f1;
        border-bottom: 14px solid #f7f7f7;
        border-left: 14px solid #f7f7f7;
        border-right: 14px solid #f1f1f1;
        border-bottom-left-radius: 3px;
        border-top-color: #fff;
        border-right-color: #fff;
      }

      .page-endpic-paper-line {
        position: absolute;
        left: 28px;
        top: 36px;
        width: 50px;
        height: 6px;
        background: #fff;

        &.l2 {
          top: 48px;
        }

        &.l3 {
          top: 60px;
        }

        &.l4 {
          top: 72px;
        }

        &.l5 {
          top: 84px;
          width: 34px;
        }
      }

      .page-endpic-angle-shadow {
        position: absolute;
        top: 28px;
        right: 0;
        width: 0;
        height: 0;
        border-top: 12.5px solid #d8d8d8;
        border-bottom: 12.5px solid transparent;
        border-left: 12.5px solid transparent;
        border-right: 12.5px solid #d8d8d8;
      }

      .page-endpic-icon-shadow {
        position: absolute;
        bottom: 0;
        right: 0;
        width: 39px;
        height: 36px;
        background-size: 100% 100%;
      }
    }

    .page-endpic-icon {
      position: absolute;
      right: -28px;
      bottom: -25px;
      width: 56px;
      height: 56px;
      background-repeat: no-repeat;
      background-size: contain;
      z-index: 2;
      animation: a-e-icon-finish 0.3s 0.7s linear both;

      @keyframes a-e-icon-finish {
        0% {
          opacity: 0;
          transform: scale(0.3, 0.5) translate(-3px, 23px);
        }

        30% {
          opacity: 1;
          transform: scale(1.15, 1.13) translate(1px, 0px);
        }

        60% {
          opacity: 1;
          transform: scale(0.96, 0.98) translate(0px, 0px);
        }

        80% {
          opacity: 1;
          transform: scale(1.12, 1.11) translate(0px, 0px);
        }

        100% {
          opacity: 1;
          transform: scale(1, 1) translate(0px, 0px);
        }
      }

      .page-endpic-icon-circle {
        fill: rgba(35, 120, 255, 1);
      }

      .page-endpic-icon-check {
        fill: rgba(255, 255, 255, 1);
      }
    }
  }
  p {
    margin-top: 40px;
  }
}

.title {
  text-align: center;
  margin-top: 20px;
  font-size: 30px;
  font-weight: normal;
  word-break: break-word;
  word-wrap: break-word;
  white-space: pre-wrap;
  line-height: 1.6;
}
.info {
  margin-top: 40px;
  font-size: 16px;
  word-break: break-word;
  word-wrap: break-word;
  white-space: pre-wrap;
  line-height: 1.6;
  text-indent: 2rem;
}

.submit {
  width: 200px;
  height: 40px;
  margin: 40px auto;
  position: relative;
  > .loading {
    width: 200px;
    height: 40px;
    padding: 0 30px;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 99;
    display: block;
    display: flex;
    align-items: center;
    justify-content: space-evenly;
    color: #fff;
    font-weight: bold;
    cursor: wait;
    svg {
      margin-top: 3px;
    }
    svg path,
    svg rect {
      fill: #fff;
    }
  }
  > .loading + button {
    color: transparent;
  }
  > button {
    width: 100%;
    height: 100%;
    background-color: #2378ff;
    color: #fff;
    font-size: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    outline: 0;
    border-radius: 4px;
    cursor: pointer;
    &:hover {
      background-color: #1f6ce5;
    }
  }
}
</style>
